package cn.itsource.basic.basic.service.impl;

import cn.itsource.basic.basic.domain.dto.EmailDto;
import cn.itsource.basic.basic.domain.dto.SendSmsDto;
import cn.itsource.basic.basic.service.IVerifyCodeService;
import cn.itsource.basic.exception.CustomException;
import cn.itsource.basic.utils.StrUtils;
import cn.itsource.basic.utils.VerifyCodeUtils;
import cn.itsource.user.domain.User;
import cn.itsource.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JavaMailSender javaMailSender;

    @Override
    public String image(String key) {
        //1.校验空值
        if (StringUtils.isEmpty(key)){
           throw  new CustomException("传入数据异常");
        }
        //2.随机生成字符串
        String randomString = StrUtils.getComplexRandomString(4);
        //3.redis保存随机生成字符串
        redisTemplate.opsForValue().set(key,randomString,5, TimeUnit.MINUTES);
        //4.生成验证码图片base64加密后的字符串
        String s = VerifyCodeUtils.VerifyCode(100, 50, randomString);
        return s;
    }

    @Override
    public String sendSmsCode(SendSmsDto sendSmsDto) {
        //1.空参数校验
        if (StringUtils.isEmpty(sendSmsDto.getMobile())){
            throw new CustomException("手机号码不能为空");
        }
        //2.判断该手机号是否已经注册
        User user = userMapper.selectByUsername(sendSmsDto.getMobile());
        if(user!=null){
            throw new CustomException("该手机号已经被注册");
        }
        //3.根据前端传递过来的图片验证码的key，去redis中获取
        Object imageCode = redisTemplate.opsForValue().get(sendSmsDto.getImageCodeKey());
        if (imageCode == null){
            //获取不到，返回自定义异常，图片验证码失效
            throw new CustomException("图片验证码失效");
        }
        //4.判断前端填写的图片验证码是否与redis中的获取的值一致
         if(!imageCode.toString().equalsIgnoreCase(sendSmsDto.getImageCode())){
             System.out.println(imageCode.toString());
             System.out.println(sendSmsDto.getImageCode());
             //5.不一致，返回自定义异常，输入的验证码错误
             throw  new CustomException("输入的验证码有误！");
         }
         //6.根据前端传递的手机号去拼接业务键后，再去redis中查询
        String smsKey = sendSmsDto.getMobile()+":register";
        Object smsCode = redisTemplate.opsForValue().get(smsKey);

        //定义一个公共的变量，用来接收最终的验证码
        String resultCode="";
        //6.1查询到有数据，判断时间是否已经过期
        if(smsCode != null){
            //获取已经存在的短信验证码的时间戳
            String timeStamp = smsCode.toString().split(":")[1];
            //判断时间戳是否已经超过一分钟，如果没有则没有过期
            if((System.currentTimeMillis()-Long.parseLong(timeStamp)) <= 1*60*1000){
                throw new CustomException("请勿重复发送短信验证码!");
            }
            //没有超时就更新延长redis里面的过期时间
            redisTemplate.opsForValue().set(smsKey,smsCode,3,TimeUnit.MINUTES);
            //准备发送老的验证码
            resultCode=smsCode.toString().split(":")[0];
        }else {
            //生成要发送的新验证码
            String newSmsCode = StrUtils.getRandomString(4);
            //生成一个要保存进redis里的value值，并且这个值拼接上当前时间的时间戳
            String newRsedisTime = newSmsCode+":"+System.currentTimeMillis();
            //保存进redis中，添加过期时间
            redisTemplate.opsForValue().set(smsKey,newRsedisTime,3,TimeUnit.MINUTES);
            //准备发送新的验证码
            resultCode=newSmsCode;
        }
        //发送验证码,没钱，所以注释下一行
        //SmsUtils.send(sendSmsDto.getMobile(),"您好，您的验证码是:"+resultCode);
        System.out.println("您好，您的验证码是:"+resultCode);
        return null;
    }

    public void  send(String a,String b,String c){
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        //设置发送人
        mailMessage.setFrom("1831595042@qq.com");
        //邮件主题
        //mailMessage.setSubject("新型冠状病毒防护指南");
        mailMessage.setSubject(a);
        //邮件内容
        // mailMessage.setText("好好在家待着ZCJ.....");
        mailMessage.setText(b);
        //收件人
        //mailMessage.setTo("1508019444@qq.com");
        //mailMessage.setTo("1831595042@qq.com");
        mailMessage.setTo(c);
        javaMailSender.send(mailMessage);
        System.out.println("发送成功");
    }

    @Override
    public String sendEmail(EmailDto emailDto) {
        //1.空参数校验
        if (StringUtils.isEmpty(emailDto.getEmail())){
            throw new CustomException("QQ号码不能为空");
        }
        //2.判断该QQ号是否已经注册
        User user =  userMapper.selectByUsername(emailDto.getEmail());
        if(user!=null){
            throw new CustomException("该QQ号已经被注册");
        }

        //6.根据前端传递的QQ号去拼接业务键后，再去redis中查询
        String smsKey = emailDto.getEmail()+":register";
        Object smsCode = redisTemplate.opsForValue().get(smsKey);
        //定义一个公共的变量，用来接收最终的验证码
        String resultCode="";
        //6.1查询到有数据，判断时间是否已经过期
        if(smsCode != null){
            //获取已经存在的QQ验证码的时间戳
            String timeStamp = smsCode.toString().split(":")[1];
            //判断时间戳是否已经超过一分钟，如果没有则没有过期
            if((System.currentTimeMillis()-Long.parseLong(timeStamp)) <= 1*60*1000){
                throw new CustomException("请勿重复发送QQ验证码!");
            }
            //没有超时就更新延长redis里面的过期时间
            redisTemplate.opsForValue().set(smsKey,smsCode,3,TimeUnit.MINUTES);
            //准备发送老的验证码
            resultCode=smsCode.toString().split(":")[0];
        }else {
            //生成要发送的新验证码
            String newSmsCode = StrUtils.getRandomString(4);
            //生成一个要保存进redis里的value值，并且这个值拼接上当前时间的时间戳
            String newRsedisTime = newSmsCode+":"+System.currentTimeMillis();
            //保存进redis中，添加过期时间
            redisTemplate.opsForValue().set(smsKey,newRsedisTime,3,TimeUnit.MINUTES);
            //准备发送新的验证码
            resultCode=newSmsCode;
        }
        //发送QQ验证码,没钱，所以注释下一行
        System.out.println("验证码："+resultCode);
        send("你的验证码：",resultCode,"1831595042@qq.com");
        return null;
    }
}
